package com.sun.apilimitrate.aspect;

import com.sun.apilimitrate.annotation.RateLimit;
import com.sun.apilimitrate.dto.Result;
import com.sun.apilimitrate.service.RedissonRateLimitService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.aspectj.lang.annotation.Aspect;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Aspect
@Component
public class RateLimitAspect {

    @Autowired
    private RedissonRateLimitService rateLimitService;

    @Autowired
    private HttpServletRequest request;

    @Around("@annotation(com.sun.apilimitrate.annotation.RateLimit)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        RateLimit rateLimit = method.getAnnotation(RateLimit.class);
        if (rateLimit == null) {
            return joinPoint.proceed();
        }

        // 获取用户ID（这里假设从请求头中获取）
        String userId = request.getHeader("X-User-Id");
        if (userId == null) {
            userId = "anonymous";
        }

        // 生成限流key：注解key + 方法名 + 用户ID
        String key = rateLimit.key() + ":" + method.getName() + ":" + userId;

        // 尝试获取令牌
        boolean acquired = rateLimitService.tryAcquire(
                key,
                1,
                rateLimit.rate(),
                rateLimit.rateInterval(),
                org.redisson.api.RateIntervalUnit.SECONDS
        );

        if (acquired) {
            return joinPoint.proceed();
        } else {
            // 被限流，返回错误信息
            return new Result(false, rateLimit.message());
        }
    }
}